<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Boost 搜索引擎</title>
    <style>
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f8f9fa;
            color: #212529;
        }
        .container {
            max-width: 800px;
            margin: auto;
            background: #fff;
            padding: 25px 30px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.07);
        }
        h1 {
            color: #343a40;
            text-align: center;
            margin-bottom: 25px;
        }
        .search-form {
            display: flex;
            margin-bottom: 30px;
        }
        .search-form input[type="text"] {
            flex-grow: 1;
            padding: 12px 15px;
            font-size: 16px;
            border: 1px solid #ced4da;
            border-radius: 4px 0 0 4px;
            box-shadow: inset 0 1px 2px rgba(0,0,0,0.075);
        }
        .search-form input[type="text"]:focus {
            border-color: #80bdff;
            outline: 0;
            box-shadow: inset 0 1px 2px rgba(0,0,0,0.075), 0 0 0 0.2rem rgba(0,123,255,.25);
        }
        .search-form button {
            padding: 12px 20px;
            font-size: 16px;
            background-color: #007bff;
            color: white;
            border: 1px solid #007bff;
            border-radius: 0 4px 4px 0;
            cursor: pointer;
            transition: background-color 0.15s ease-in-out;
        }
        .search-form button:hover {
            background-color: #0056b3;
        }
        .results-area {
            margin-top: 20px;
        }
        .result-item {
            background: #fff;
            padding: 15px 0;
            margin-bottom: 20px;
            border-bottom: 1px solid #e9ecef;
        }
        .result-item:last-child {
            border-bottom: none;
            margin-bottom: 0;
        }
        .result-item .title a {
            font-size: 20px;
            color: #1a0dab;
            text-decoration: none;
            font-weight: normal;
            display: block;
            margin-bottom: 3px;
        }
        .result-item .title a:hover {
            text-decoration: underline;
        }
        .result-item .description {
            font-size: 14px;
            color: #4d5156;
            line-height: 1.57;
            margin-bottom: 3px;
            display: -webkit-box;
            -webkit-line-clamp: 3;
            line-clamp: 3;
            -webkit-box-orient: vertical;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .result-item .url-display {
            font-size: 14px;
            color: #202124;
            margin-bottom: 4px;
            display: block;
        }
         .result-item .url-display em {
            font-style: italic;
        }
        .status-message {
            text-align: center;
            font-size: 16px;
            color: #6c757d;
            padding: 20px 0;
        }
        .pagination {
            display: flex;
            justify-content: center;
            align-items: center;
            margin-top: 30px;
            padding-top: 20px;
            border-top: 1px solid #e9ecef;
        }
        .pagination button, .pagination span {
            margin: 0 5px;
            padding: 8px 12px;
            border: 1px solid #dee2e6;
            background-color: #fff;
            color: #007bff;
            cursor: pointer;
            border-radius: 4px;
            user-select: none;
        }
        .pagination button:hover:not(:disabled), .pagination span:not(.active):not(.dots):hover {
            background-color: #e9ecef;
        }
        .pagination button:disabled {
            color: #6c757d;
            cursor: not-allowed;
            background-color: #f8f9fa;
        }
        .pagination span.active {
            background-color: #007bff;
            color: white;
            border-color: #007bff;
            cursor: default;
        }
        .pagination span.dots {
            border: none;
            cursor: default;
            padding: 8px 0;
            color: #6c757d;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Boost 搜索引擎</h1>

        <div class="search-form">
            <input type="text" id="searchInput" placeholder="请输入搜索关键词..." aria-label="搜索关键词">
            <button id="searchButton">搜索</button>
        </div>

        <div id="resultsArea" class="results-area">
            </div>

        <div id="paginationArea" class="pagination">
            </div>
    </div>

    <script>
        const searchInput = document.getElementById('searchInput');
        const searchButton = document.getElementById('searchButton');
        const resultsArea = document.getElementById('resultsArea');
        const paginationArea = document.getElementById('paginationArea');

        const ITEMS_PER_PAGE = 8;
        let allResults = [];
        let currentPage = 1;

        // 函数：从URL获取搜索词
        function getQueryFromUrl() {
            const urlParams = new URLSearchParams(window.location.search);
            return urlParams.get('word');
        }

        // 函数：执行实际的搜索逻辑 (获取数据和显示)
        async function performSearchLogic(query) {
            if (!query) {
                resultsArea.innerHTML = '<p class="status-message">请输入有效的搜索关键词。</p>';
                paginationArea.innerHTML = '';
                allResults = []; // 清空结果
                return;
            }

            // 更新搜索框的值，确保与当前搜索一致
            if (searchInput.value !== query) {
                searchInput.value = query;
            }

            resultsArea.innerHTML = '<p class="status-message">正在搜索中...</p>';
            paginationArea.innerHTML = '';

            try {
                // 你的API端点仍为 /s?word=...
                const response = await fetch(`/s?word=${encodeURIComponent(query)}`);
                if (!response.ok) {
                    const errorText = await response.text();
                    let detail = errorText;
                     try { // 尝试解析可能的JSON错误
                        const errorJson = JSON.parse(errorText);
                        if (errorJson && (errorJson.error || errorJson.message)) {
                            detail = errorJson.error || errorJson.message;
                        } else if (typeof errorJson === 'string') {
                             detail = errorJson;
                        }
                    } catch(e) { /* 不是JSON，保持纯文本 */ }

                    // 检查后端直接返回的文本错误，例如 "搜索需要提供关键字"
                    if (response.status === 200 && detail.includes("搜索需要提供关键字")) {
                         throw new Error(detail); // 即使status是200，如果内容是错误提示也认为是错误
                    } else {
                         throw new Error(`搜索请求失败: ${response.status} - ${detail}`);
                    }
                }
                allResults = await response.json();
                currentPage = 1; // 每次新搜索都重置到第一页
                displayPage(currentPage);
                setupPagination();
            } catch (error) {
                console.error('搜索过程中发生错误:', error);
                resultsArea.innerHTML = `<p class="status-message">搜索失败: ${error.message}</p>`;
                allResults = [];
                paginationArea.innerHTML = '';
            }
        }

        // 函数：更新URL并触发搜索（但不直接执行，而是让 popstate 或初始加载处理）
        function updateUrlAndInitiateSearch(query) {
            const currentUrlQuery = getQueryFromUrl();
            if (query === currentUrlQuery) { // 如果查询词没变，可以考虑是否重新搜索
                performSearchLogic(query); // 或者直接返回，避免不必要的重载
                return;
            }

            const newUrl = new URL(window.location.origin + window.location.pathname);
            if (query) {
                newUrl.searchParams.set('word', query);
            }
            // 更新浏览器历史记录和地址栏URL
            // 第三个参数是URL。使用 `newUrl.href` 或 `newUrl.pathname + newUrl.search`
            history.pushState({ query: query }, `搜索: ${query}`, newUrl.pathname + newUrl.search);
            
            // history.pushState 不会触发 popstate, 所以需要手动调用搜索逻辑
            performSearchLogic(query);
        }

        // 函数：根据当前URL加载内容 (用于初始加载和浏览器后退/前进)
        function loadContentFromUrl() {
            const query = getQueryFromUrl();
            if (query) {
                performSearchLogic(query);
            } else {
                // 如果URL中没有word参数，显示初始提示
                resultsArea.innerHTML = '<p class="status-message">欢迎使用Boost搜索引擎，请输入关键词开始搜索。</p>';
                paginationArea.innerHTML = '';
                allResults = [];
                searchInput.value = ''; // 清空搜索框
            }
        }

        // 事件监听：搜索按钮点击
        searchButton.addEventListener('click', () => {
            const query = searchInput.value.trim();
            if (query) {
                updateUrlAndInitiateSearch(query);
            } else {
                // 如果搜索框为空，可以选择清除URL中的word参数并显示初始状态
                history.pushState({}, document.title, window.location.pathname);
                loadContentFromUrl(); // 会显示初始提示
            }
        });

        // 事件监听：搜索框回车
        searchInput.addEventListener('keypress', function(event) {
            if (event.key === 'Enter') {
                event.preventDefault(); // 防止表单提交（如果未来放入form中）
                const query = searchInput.value.trim();
                 if (query) {
                    updateUrlAndInitiateSearch(query);
                } else {
                    history.pushState({}, document.title, window.location.pathname);
                    loadContentFromUrl();
                }
            }
        });

        // 事件监听：浏览器历史导航 (后退/前进按钮)
        window.addEventListener('popstate', function(event) {
            // event.state 可能为 null (例如，如果初始页面没有pushState)
            // 或者包含我们 pushState 时设置的 { query: ... } 对象
            loadContentFromUrl(); // 重新根据URL加载内容
        });

        // 初始页面加载时，检查URL是否有搜索词并执行搜索
        document.addEventListener('DOMContentLoaded', function() {
            loadContentFromUrl();
        });


        // --- 以下是 displayPage 和 setupPagination 函数 (与之前版本类似，略作调整) ---
        function displayPage(page) {
            currentPage = page;
            resultsArea.innerHTML = '';

            if (!allResults || allResults.length === 0) {
                // performSearchLogic中已经处理了空结果，这里主要用于分页切换时
                if(getQueryFromUrl()){ // 只有当确实进行过有效搜索后才显示“无结果”
                     resultsArea.innerHTML = '<p class="status-message">没有找到相关结果。</p>';
                }
                return;
            }

            const startIndex = (page - 1) * ITEMS_PER_PAGE;
            const endIndex = startIndex + ITEMS_PER_PAGE;
            const paginatedResults = allResults.slice(startIndex, endIndex);

            if (paginatedResults.length === 0 && page > 1) {
                resultsArea.innerHTML = '<p class="status-message">这一页没有更多结果了。</p>';
                return;
            }


            paginatedResults.forEach(item => {
                const resultItemDiv = document.createElement('div');
                resultItemDiv.className = 'result-item';

                const titleDiv = document.createElement('div');
                titleDiv.className = 'title';
                const titleLink = document.createElement('a');
                titleLink.href = item.url || '#';
                titleLink.target = '_blank';
                titleLink.textContent = item.title || '无标题';
                titleDiv.appendChild(titleLink);

                const descParagraph = document.createElement('div');
                descParagraph.className = 'description';
                descParagraph.textContent = item.desc || '无可用描述';

                const urlDiv = document.createElement('div');
                urlDiv.className = 'url-display';
                const urlEm = document.createElement('em');
                urlEm.textContent = item.url || '无URL';
                urlDiv.appendChild(urlEm);

                resultItemDiv.appendChild(titleDiv);
                resultItemDiv.appendChild(descParagraph);
                resultItemDiv.appendChild(urlDiv);

                resultsArea.appendChild(resultItemDiv);
            });
            updatePaginationActiveState();
        }

        function setupPagination() {
            paginationArea.innerHTML = '';
            if (!allResults || allResults.length === 0) {
                return;
            }

            const totalPages = Math.ceil(allResults.length / ITEMS_PER_PAGE);
            if (totalPages <= 1) {
                return;
            }

            const prevButton = document.createElement('button');
            prevButton.textContent = '上一页';
            prevButton.onclick = () => {
                if (currentPage > 1) {
                    displayPage(currentPage - 1);
                }
            };
            paginationArea.appendChild(prevButton);

            const maxPageLinks = 5;
            let startPage, endPage;
            if (totalPages <= maxPageLinks + 2) {
                startPage = 1; endPage = totalPages;
            } else {
                const sideWidth = Math.floor(maxPageLinks / 2);
                if (currentPage <= sideWidth + 1) {
                    startPage = 1; endPage = maxPageLinks;
                } else if (currentPage >= totalPages - sideWidth) {
                    startPage = totalPages - maxPageLinks + 1; endPage = totalPages;
                } else {
                    startPage = currentPage - sideWidth; endPage = currentPage + sideWidth;
                }
            }

            if (startPage > 1) {
                const firstPageSpan = document.createElement('span');
                firstPageSpan.textContent = '1';
                firstPageSpan.onclick = () => displayPage(1);
                paginationArea.appendChild(firstPageSpan);
                if (startPage > 2) {
                    const dots = document.createElement('span');
                    dots.textContent = '...';
                    dots.className = 'dots';
                    paginationArea.appendChild(dots);
                }
            }

            for (let i = startPage; i <= endPage; i++) {
                if (i === 1 && startPage > 1) continue;
                if (i === totalPages && endPage < totalPages) continue;
                const pageSpan = document.createElement('span');
                pageSpan.textContent = i;
                pageSpan.onclick = () => displayPage(i);
                paginationArea.appendChild(pageSpan);
            }

            if (endPage < totalPages) {
                if (endPage < totalPages - 1) {
                    const dots = document.createElement('span');
                    dots.textContent = '...';
                    dots.className = 'dots';
                    paginationArea.appendChild(dots);
                }
                const lastPageSpan = document.createElement('span');
                lastPageSpan.textContent = totalPages;
                lastPageSpan.onclick = () => displayPage(totalPages);
                paginationArea.appendChild(lastPageSpan);
            }

            const nextButton = document.createElement('button');
            nextButton.textContent = '下一页';
            nextButton.onclick = () => {
                if (currentPage < totalPages) {
                    displayPage(currentPage + 1);
                }
            };
            paginationArea.appendChild(nextButton);
            updatePaginationActiveState();
        }

        function updatePaginationActiveState() {
            const pageSpans = paginationArea.querySelectorAll('span:not(.dots)');
            pageSpans.forEach(span => {
                if (parseInt(span.textContent) === currentPage) {
                    span.classList.add('active');
                } else {
                    span.classList.remove('active');
                }
            });
            const prevButton = paginationArea.querySelector('button:first-of-type');
            const nextButton = paginationArea.querySelector('button:last-of-type');
            const totalPages = Math.ceil(allResults.length / ITEMS_PER_PAGE);
            if (prevButton) prevButton.disabled = (currentPage === 1);
            if (nextButton) nextButton.disabled = (currentPage === totalPages || totalPages === 0);
        }
    </script>
</body>
</html>
